-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Offset: Eliminate Dimples #669
Conversation
* update formatting * update formatter
* example url * update * format * address comments * fix formatting
Add WarpBatch - array process warp with single callback
* [python] numpy updates and cleanup Also add CrossSection::Bounds() * cleanup - const and reference args in py bind * fix unnamed args * all_apis.py more coverage * fixup - more param renaming, docstring fixes * fixup - run black * fixup - move const to left side * fixup extrude.py get_volume * fix python examples for api update
Easier than I expected!
Dimple Measurement It seems like the floater triangles have gotten worse though; let's try switching that part back to the warp based implementation... EDIT: Yep, switching back to the triangle warping implementation for the triangle extrusion fixed the floaters... so weird. I guess Quickhull is reducing the precision somehow... |
Hrm, I’ll need to make it so the circular arcs have a variable number of segments based on the angle they subtend. Maybe specify as “degrees per segment”. |
Alrighty, I have I’d expect to get perfect topology at these corners by projecting the wedges to spherical coordinates, doing a dense delaunay triangulation (with poisson samples points in the polygon?), and projecting back to Cartesian coordinates… but this topology should do for now. Alternatively, the topology looks a lot better when the circularArc resolution is a lot higher than the sphere resolution (as it does in the comparison shots before this comment); not sure what to make of that… |
@elalish You might find the above explorations entertaining; it seems like the Minkowski Offsetting method is more robust for layered morphological operations at the moment. Also worth noting: the Minkowski Offset doesn't experience any degradation when the shape rotates, but the topology of the borders around the interior spherecaps become a little crunchy. (But the surface normals appears to be fine, so it's a method without drawbacks, save for speed.) |
Yeah, I think you've convinced me on the Minkowski. I'm guessing we can abandon this and #668? |
I’m kind of hopeful that there’s a version of the spherical case that is more robust… iirc it’s over twice as fast as the Minkowski case, and increasing the resolution is a lot cheaper, especially if I can figure out an elegant way to do interpolating spherecaps. The primary issue for layered morphology is taking care of the corrupting precision issues, which might come for free in the PR that switches everything to I suppose the poor man’s vertex merge is quantizing the vertex positions as keys, storing them in an unordered map, and snapping the warp and circular arc positions to them at every step, ensuring that the vertices are coincident before the hulls and booleans. That, and maybe loosening the tolerance on determining convex edges 🤔 But I probably won’t get to it before the new year; stepping away from my computer for a week starting tomorrow. 🫠 |
OpenSCAD does this for their VBO preview, and the performance is... not very good. openscad/openscad#4883 |
btw I noticed the quickhull module often print |
The even poorer man’s version is to just quantize the vertices and not preserve any exactness 🫠
I’m just not totally sure if it’s the source of my headaches, since I don’t see it that often 😅 |
I tried implementing the naive minkowski on openscad, and do get them frequently (a few times per model in the benchmarks) iirc. I thought it is already using double? not sure about that. |
Huh; hadn’t realized OpenSCAD used the same library; I bet it comes from those really crunchy sections where the number of triangles just blows up. For the particular situation in this thread, I think it’s possible to do the “fillet all edges by radius” operation in one pass without introducing any crunchiness; maybe that’s the 50%-case operation that people actually want from minkowski() and offset()? I’d have to look at it after Christmas (maybe New Years?) if it is something people want 😅 The key is that Circumcenter code from the Voronoi PR, which will find where to center the exterior circular arcs and spheres to acquire the desired radii 💪 EDIT: |
no, I mean when they use manifold and manifold calls quickhull. They use CGAL hull in general.. |
To be clear, switching to And quantizing verts to merge them is also a great way to destroy manifoldness - this is exactly why the STL file format can't reliably transmit a manifold. Turns out it just creates even more heinous topology that is nearly impossible to correct in general. The fact that this special sphere minkowski only gets maybe a 2x speed up tells me its not worth pursuing. If it was 10x, sure, but for the code maintenance burden, I think regular Minkowski is fine. I might make an offset API for convenience though. |
Thinking about it, there’s probably a market for Offsetting algorithms that don’t increase the number of faces (ala the normal calculation routine in the image here): Calculating average vertex normals first, and then using the Triangle Warp Union on a bunch of extruded vertex triangle faces would handle self-intersections, be fast, and sometimes even be the desired behavior (like when wanting to make a box hollow, preserving sharp edges). Vertex Normal Extrusion/Dilation is done all the time in video games, but not in a Manifold-preserving way 😄 EDIT: Probably best to define extrusion amount, resolution (where 0 is a per-vertex extrusion), and Boolean Operation (Union, Subtraction, Intersection)… |
* python autogen docstrings * use function signature hashes in docstring key * remove sys.path debug code * docstrings use param names * autogen docstrings during cmake * document gen_docs.py * more readme, remap mesh_gl references * readme about verify python docstrings, autogen depend on sources
Our |
Ah, I was confused about warp 😅 Just pushed a first-draft (broken) per-vertex-offset implementation: My expectation (as a user) would be that it does something like this when the |
I'm going to go ahead and close this and #668 in favor of #666 for now. I'm not super interested in having a bunch of different offsetting algorithms in |
Alrighty; I'll see if I can make a minimal case. 👍 |
I had a good idea for the offset implementation while thinking about how OpenCascade does it.
This PR changes how @elalish 's Offset works:
The warped triangles are replaced with a hull of the vertices and their extruded positions (somehow faster in my testing?)Not actually faster, switched back.The first part fixes the edge dimples, and improves the resolution the offset along convex edges.
The second part fixes the edge dimples that end at the spherical caps.
The third part is just simpler and brought the time down from 1600ms to 1300ms on my test part somehow; not sure why.The speed of this general process could probably be vastly improved by replacing the spheres with multi-wedge interpolations (map wedges 2D pitch/yaw space, add a bunch more points, delaunay triangulate, lift to 3D again), removing all of the CSG operations, and stitching the faces together by the coincident vertices at the end.
This PR still suffers from the precision issues that Emmett noticed earlier, but they're usually between the extruded triangles on flat faces.
Emmet's PR:
This PR (Old, before
circularSegments
was tuned to match; it does show that edgeResolution and sphereResolution are two independently tunable parameters now):OpenCascade Reference: